﻿<%@ Page Culture="en-US" Language="C#" %>

<%@ Import Namespace="System.Globalization" %>
<%@ Import Namespace="System.Linq" %>
<%@ Import Namespace="System.Xml.Linq" %>

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<script runat="server">
    XDocument items;
    NameValueCollection queryStrings;
    bool showComments = false;
    string version = "0.1 alpha";
    
    void Page_Init(object sender, EventArgs e)
    {
        items = XDocument.Load(MapPath(@"App_Data\Items.xml"));
        queryStrings = Request.QueryString;

        if (queryStrings.Count == 0)
            // FIXME: Length should be hardcoded elsewhere
            lvItems.DataSource = QueryLastItems(10);
        else
        {
            CheckWrongQueryStrings();

            switch (queryStrings.Keys[0])
            {
                case "c":
                    // FIXME: Check for special characters
                    lvItems.DataSource = QueryLastItems(10, queryStrings[0]);
                    break;
                case "d":
                    lvItems.DataSource = QueryItems(DateTime.Parse(queryStrings[0]));
                    break;
                case "f":
                    ExportFeed(10, queryStrings[0]);
                    break;
                case "i":
                    lvItems.DataSource = QueryItem(Int32.Parse(queryStrings[0]));
                    break;
                default:
                    break;
            }
        }
        
        lvItems.DataBind();
        PopulateArchive();
    }

    protected void btnDate_OnClick(object sender, EventArgs e)
    {
        Response.Redirect(string.Format("{0}Default.aspx?d={1}", ConfigurationSettings.AppSettings["url"], ddlArchive.SelectedValue));
    }

    void CheckWrongQueryStrings()
    {
        bool wellFormed = true;

        switch (queryStrings.Keys[0])
        {
            case "c":
                // FIXME: Check for special characters
                wellFormed = Regex.IsMatch(queryStrings[0], "^[a-zA-Z]{1,}$");
                break;
            case "d":
                wellFormed = Regex.IsMatch(queryStrings[0], @"^(0[1-9]|1[012])-(19|20)\d\d$");
                break;
            case "f":
                wellFormed = queryStrings[0] == "rss";
                break;
            case "i":
                wellFormed = Regex.IsMatch(queryStrings[0], "^[0-9]{1,}$");
                break;
            default:
                break;
        }
        
        if (!wellFormed)
            Response.Redirect(string.Format("{0}Default.aspx", ConfigurationSettings.AppSettings["url"]));
    }

    void ExportFeed(int length, string type)
    {
        // FIXME: Check for type, RSS by default
        // FIXME: Support caching
        XNamespace atom = "http://www.w3.org/2005/Atom";
        string permaLink = string.Format("{0}Default.aspx?i=", ConfigurationSettings.AppSettings["url"]);
        
        XElement feed = new XElement("rss",
            new XAttribute("version", "2.0"),
            new XAttribute(XNamespace.Xmlns + "atom", atom.NamespaceName),
            new XElement("channel",
                new XElement("title", ConfigurationSettings.AppSettings["title"]),
                new XElement("link", ConfigurationSettings.AppSettings["url"]),
                new XElement("description", ConfigurationSettings.AppSettings["description"]),
                new XElement("copyright", ConfigurationSettings.AppSettings["author"]),
                new XElement("managingEditor", string.Format("{0} ({1})", ConfigurationSettings.AppSettings["e-mail"], ConfigurationSettings.AppSettings["author"])),
                new XElement("generator", "Amelio"),
                new XElement(atom + "link",
                    new XAttribute("href", string.Format("{0}Default.aspx?f=rss", ConfigurationSettings.AppSettings["url"])),
                    new XAttribute("rel", "self"),
                    new XAttribute("type", "application/rss+xml")),
                (from item in items.Descendants("Item")
                select new XElement("item",
                    new XElement("title", item.Element("Title").Value),
                    new XElement("link", string.Format("{0}{1}", permaLink, item.Attribute("id").Value)),
                    new XElement("description", item.Element("Content").Value),
                    // FIXME: pubDate must be an RFC-822 date-time
                    new XElement("pubDate", item.Element("Date").Value),
                    new XElement("guid", string.Format("{0}{1}", permaLink, item.Attribute("id").Value))
                    )).Take(length)
                )
            );
        // FIXME: Hackish?
        Response.ContentType = "text/xml";
        Response.Write(feed);
        Response.Flush();
        Response.End();
    }

    void PopulateArchive()
    {
        ddlArchive.DataSource = (from item in items.Descendants("Item")
                                 select new
                                 {
                                     Date = DateTime.Parse(item.Element("Date").Value).ToString("Y"),
                                     // FIXME: Figure out the best format, currently working but culture dependent
                                     Value = DateTime.Parse(item.Element("Date").Value).ToString("MM-yyyy")
                                 }).Distinct();
        ddlArchive.DataBind();
    }

    // FIXME: Should id be string? 2 Int32.Parse() less
    IEnumerable QueryItem(int id)
    {
        showComments = true;
        
        return from item in items.Descendants("Item")
               where Int32.Parse(item.Attribute("id").Value) == id
               select new
               {
                   Id = item.Attribute("id").Value,
                   Title = item.Element("Title").Value,
                   Date = item.Element("Date").Value,
                   Categories = (from category in item.Descendants("Category")
                                 orderby category.Value
                                 select category.Value).ToList(),
                   Content = item.Element("Content").Value
               };
    }

    IEnumerable QueryItems(DateTime date)
    {
        return from item in items.Descendants("Item")
               // FIXME: Hackish? Likely
               where DateTime.Parse(item.Element("Date").Value).Month == date.Month && DateTime.Parse(item.Element("Date").Value).Year == date.Year
               select new
               {
                   Id = item.Attribute("id").Value,
                   Title = item.Element("Title").Value,
                   Date = item.Element("Date").Value,
                   Categories = (from category in item.Descendants("Category")
                                 orderby category.Value
                                 select category.Value).ToList(),
                   Content = item.Element("Content").Value
               };
    }

    IEnumerable QueryLastItems(int length)
    {
        return (from item in items.Descendants("Item")
                select new
                {
                    Id = item.Attribute("id").Value,
                    Title = item.Element("Title").Value,
                    Date = item.Element("Date").Value,
                    Categories = (from category in item.Descendants("Category")
                                  orderby category.Value
                                  select category.Value).ToList(),
                    Content = item.Element("Content").Value
                }).Take(length);
    }

    IEnumerable QueryLastItems(int length, string category)
    {
        return (from item in items.Descendants("Item")
                where item.Element("Categories").Elements("Category").Any(c => c.Value == category)
                select new
                {
                    Id = item.Attribute("id").Value,
                    Title = item.Element("Title").Value,
                    Date = item.Element("Date").Value,
                    Categories = (from c in item.Descendants("Category")
                                  orderby c.Value
                                  select c.Value).ToList(),
                    Content = item.Element("Content").Value
                }).Take(length);
    }
</script>

<html xmlns="http://www.w3.org/1999/xhtml">
<head runat="server">
    <title><%=ConfigurationSettings.AppSettings["title"] %></title>
</head>
<body>
    <div class="blog">
        <form id="frmBlog" runat="server">
            <div class="header">
                <a href="<%=ConfigurationSettings.AppSettings["url"] %>"><%=ConfigurationSettings.AppSettings["title"] %></a>
                <div class="header-description"><%=ConfigurationSettings.AppSettings["description"] %></div>
            </div>
            <div class="menu">
                Choose a date: 
                <asp:DropDownList DataTextField="Date" DataValueField="Value" ID="ddlArchive" runat="server">
                </asp:DropDownList> 
                <asp:Button ID="btnDate" OnClick="btnDate_OnClick" runat="server" Text="Go!" /> | 
                Contact: <%=ConfigurationSettings.AppSettings["e-mail"] %> | 
                Export items as: <a href="<%=ConfigurationSettings.AppSettings["url"] %>Default.aspx?f=rss">RSS</a>
            </div>
            <asp:ListView ID="lvItems" runat="server">
                <LayoutTemplate>
                    <div id="itemPlaceholder" runat="server"></div>
                </LayoutTemplate>
                <ItemTemplate>
                    <div class="item">
                        <div class="title">
                            <a href="<%=ConfigurationSettings.AppSettings["url"] %>Default.aspx?i=<%#Eval("Id") %>"><%#Eval("Title") %></a>
                        </div>
                        <div class="information">
                            Digitalized on <%#DateTime.Parse(Eval("Date").ToString()).ToString("F") %> under 
                            <asp:Repeater DataSource='<%#Eval("Categories") %>' ID="rptCategories" runat="server">
                                <ItemTemplate>
                                    <a href="<%=ConfigurationSettings.AppSettings["url"] %>Default.aspx?c=<%#Container.DataItem %>"><%#Container.DataItem %></a>
                                </ItemTemplate>
                                <SeparatorTemplate>, </SeparatorTemplate>
                            </asp:Repeater> 
                            by <%=ConfigurationSettings.AppSettings["author"] %>
                        </div>
                        <div class="content">
                            <%#Eval("Content") %>
                        </div>
                        <%#showComments ? ConfigurationSettings.AppSettings["comments-snippet"] : string.Format("<a href='{0}Default.aspx?i={1}#disqus_thread'>Comments (View)</a>", ConfigurationSettings.AppSettings["url"], Eval("Id"))%>
                    </div>
                </ItemTemplate>
                <EmptyDataTemplate>
                    Sorry, your request returned no items.
                </EmptyDataTemplate>
            </asp:ListView>
            <div class="footer">
                &copy; 2006-08 <%=ConfigurationSettings.AppSettings["author"] %><br />
                Generated by Amelio ver. <%=version %>
            </div>
        </form>
    </div>
    <script type="text/javascript">
        //<[CDATA[
        (function() {
		        var links = document.getElementsByTagName('a');
		        var query = '?';
		        for(var i = 0; i < links.length; i++) {
			        if(links[i].href.indexOf('#disqus_thread') >= 0) {
				        query += 'url' + i + '=' + encodeURIComponent(links[i].href) + '&';
			        }
		        }
		        document.write('<script type="text/javascript" src="http://disqus.com/forums/straybirds130/get_num_replies.js' + query + '"></' + 'script>');
	        })();
        //]]>
    </script>
    <script type="text/javascript">
        var gaJsHost = (("https:" == document.location.protocol) ? "https://ssl." : "http://www.");
        document.write(unescape("%3Cscript src='" + gaJsHost + "google-analytics.com/ga.js' type='text/javascript'%3E%3C/script%3E"));
    </script>
    <script type="text/javascript">
        var pageTracker = _gat._getTracker("<%=ConfigurationSettings.AppSettings["google-analytics-ua"] %>");
        pageTracker._initData();
        pageTracker._trackPageview();
    </script>
</body>
</html>
